Effective Python: 90 Specific Ways to Write Better Python, 2nd Edition by Brett Slatkin
Author:Brett Slatkin [Brett Slatkin]
Language: eng
Format: epub
Publisher: Addison-Wesley Professional
Published: 2019-11-21T16:00:00+00:00
✦ Descriptors and metaclasses make a powerful combination for declarative behavior and runtime introspection.
✦ Define __set_name__ on your descriptor classes to allow them to take into account their surrounding class and its property names.
✦ Avoid memory leaks and the weakref built-in module by having descriptors store data they manipulate directly within a class’s instance dictionary.
Item 51: Prefer Class Decorators Over Metaclasses for Composable Class Extensions
Although metaclasses allow you to customize class creation in multiple ways (see Item 48: “Validate Subclasses with __init_subclass__” and Item 49: “Register Class Existence with __init_subclass__”), they still fall short of handling every situation that may arise.
For example, say that I want to decorate all of the methods of a class with a helper that prints arguments, return values, and exceptions raised. Here, I define the debugging decorator (see Item 26: “Define Function Decorators with functools.wraps” for background):
Click here to view code image
from functools import wraps def trace_func(func): if hasattr(func, 'tracing'): # Only decorate once return func @wraps(func) def wrapper(*args, **kwargs): result = None try: result = func(*args, **kwargs) return result except Exception as e: result = e raise finally: print(f'{func.__name__}({args!r}, {kwargs!r}) -> ' f'{result!r}') wrapper.tracing = True return wrapper
I can apply this decorator to various special methods in my new dict subclass (see Item 43: “Inherit from collections.abc for Custom Container Types” for background):
Click here to view code image
class TraceDict(dict): @trace_func def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) @trace_func def __setitem__(self, *args, **kwargs): return super().__setitem__(*args, **kwargs) @trace_func def __getitem__(self, *args, **kwargs): return super().__getitem__(*args, **kwargs) ...
And I can verify that these methods are decorated by interacting with an instance of the class:
Click here to view code image
trace_dict = TraceDict([('hi', 1)]) trace_dict['there'] = 2 trace_dict['hi'] try: trace_dict['does not exist'] except KeyError: pass # Expected >>> __init__(({'hi': 1}, [('hi', 1)]), {}) -> None __setitem__(({'hi': 1, 'there': 2}, 'there', 2), {}) -> None __getitem__(({'hi': 1, 'there': 2}, 'hi'), {}) -> 1 __getitem__(({'hi': 1, 'there': 2}, 'does not exist'), ➥ {}) -> KeyError('does not exist')
The problem with this code is that I had to redefine all of the methods that I wanted to decorate with @trace_func. This is redundant boilerplate that’s hard to read and error prone. Further, if a new method is later added to the dict superclass, it won’t be decorated unless I also define it in TraceDict.
One way to solve this problem is to use a metaclass to automatically decorate all methods of a class. Here, I implement this behavior by wrapping each function or method in the new type with the trace_func decorator:
Click here to view code image
import types trace_types = ( types.MethodType, types.FunctionType, types.BuiltinFunctionType, types.BuiltinMethodType, types.MethodDescriptorType, types.ClassMethodDescriptorType) class TraceMeta(type): def __new__(meta, name, bases, class_dict): klass = super().__new__(meta, name, bases, class_dict) for key in dir(klass): value = getattr(klass, key) if isinstance(value, trace_types): wrapped = trace_func(value) setattr(klass, key, wrapped) return klass
Now, I can declare my dict subclass by using the TraceMeta metaclass and verify that it works as expected:
Click here to view code image
class TraceDict(dict, metaclass=TraceMeta): pass trace_dict = TraceDict([('hi', 1)]) trace_dict['there'] = 2 trace_dict['hi'] try: trace_dict['does not exist'] except KeyError: pass # Expected >>> __new__((<class '__main__.
Download
This site does not store any files on its server. We only index and link to content provided by other sites. Please contact the content providers to delete copyright contents if any and email us, we'll remove relevant links or contents immediately.
Eco-friendly approach of bio-indigo synthesis and developing purification methods towards isolation of indigo from indirubin and bacterial fragments by Ramalingam Manivannan & Kaliyan Prabakaran & Young-A Son(155706)
Whisky: Malt Whiskies of Scotland (Collins Little Books) by dominic roskrow(74275)
CONSORT 2025 statement: updated guideline for reporting randomized trials by unknow(66079)
Critical evaluation of the ProfiLER-02 study design and outcomes by Vivek Subbiah & Razelle Kurzrock(65827)
Cardiac gene therapy makes a comeback by Oliver J. Müller & Susanne Hille & Anca Kliesow Remes(65265)
Unveiling the design rules for tunable emission in graphene quantum dots: A high-throughput TDDFT and machine learning perspective by Şener Özönder & Mustafa Coşkun Özdemir & Caner Ünlü(50858)
A yeast-based oral therapeutic delivers immune checkpoint inhibitors to reduce intestinal tumor burden by unknow(39224)
Covalent hitchhikers guide proteins to the nucleus by Alexander F. Russell & Madeline F. Currie & Champak Chatterjee(39207)
Meet the Authors: Christopher R. Mansfield and Emily R. Derbyshire by Christopher R. Mansfield & Emily R. Derbyshire(39095)
What's Done in Darkness by Kayla Perrin(27103)
Topological analysis of non-conjugated ethylene oxide cored dendrimers decorated with tetraphenylethylene: Insights from degree-based descriptors using the polynomial approach by A Theertha Nair & D Antony Xavier & Annmaria Baby & S Akhila(26484)
Investigation of mechanical and self-healing properties of hydroxyl-terminated polybutadiene functionalized with 2-ureido-4-pyrimidinone by Mohsen Kazazi & Mehran Hayaty & Ali Mousaviazar(26435)
The Ultimate Python Exercise Book: 700 Practical Exercises for Beginners with Quiz Questions by Copy(21017)
De Souza H. Master the Age of Artificial Intelligences. The Basic Guide...2024 by Unknown(20775)
D:\Jan\FTP\HOL\Work\Alien Breed - Tower Assault CD32 Alien Breed II - The Horror Continues Manual 1.jpg by PDFCreator(20648)
The Fifty Shades Trilogy & Grey by E L James(19605)
Shot Through the Heart: DI Grace Fisher 2 by Isabelle Grey(19487)
Shot Through the Heart by Mercy Celeste(19349)
Python GUI Applications using PyQt5 : The hands-on guide to build apps with Python by Verdugo Leire(17492)